"""
HiAgent API客户端工具类
"""
import json
import requests
from typing import Dict, Any, Optional
from collections import OrderedDict
from email.utils import formatdate

try:
    from volcengine.auth.SignerV4 import SignerV4
    from volcengine.auth.SignParam import SignParam
    from volcengine.Credentials import Credentials
except ImportError:
    # 如果没有安装volcengine SDK，提供简单的替代实现
    class SignerV4:
        def sign(self, param, credentials):
            pass
    
    class SignParam:
        def __init__(self):
            self.path = None
            self.method = None
            self.host = None
            self.query = None
            self.headers = None
            self.header_list = None
            self.body = None
    
    class Credentials:
        def __init__(self, ak, sk, service, region):
            pass

from src.llm.hiagent_app.config.hiagent_config import HiAgentConfig


class HiAgentAPIClient:
    """HiAgent API客户端"""
    
    def __init__(self, config: Optional[HiAgentConfig] = None):
        self.config = config or HiAgentConfig()
        self.session = requests.Session()
        
    def _create_signature_params(
        self,
        action: str,
        body: Dict[str, Any],
        version: Optional[str] = None,
        service: Optional[str] = None,
        region: Optional[str] = None
    ) -> SignParam:
        """创建签名参数

        Args:
            action: API动作
            body: 请求体
            version: API版本 (可选，默认使用config.VERSION)
            service: 服务名称 (可选，默认使用config.SERVICE)
            region: 区域 (可选，默认使用config.REGION)
        """
        param = SignParam()
        param.path = self.config.PATH
        param.method = 'POST'
        param.host = self.config.HOST

        # 使用传入的参数或默认配置
        use_version = version or self.config.VERSION
        use_service = service or self.config.SERVICE
        use_region = region or self.config.REGION

        # 保存服务和区域信息供签名使用
        param.service = use_service
        param.region = use_region

        # 设置查询参数
        query = OrderedDict()
        query['Action'] = action
        query['Version'] = use_version
        query['X-Account-Id'] = self.config.ACCOUNT_ID
        param.query = query

        # 设置请求头
        headers = OrderedDict()
        headers['Host'] = self.config.HOST
        headers['Content-Type'] = 'application/json'
        # 手动添加X-Date头，防止线上环境缺失
        headers['X-Date'] = formatdate(timeval=None, localtime=False, usegmt=True)
        param.header_list = headers
        param.headers = headers

        # 设置请求体
        param.body = json.dumps(body)

        return param
    
    def _sign_request(self, param: SignParam) -> None:
        """签名请求"""
        print(f"\n[DEBUG] Signing request...")
        print(f"  Headers before signing: {list(param.headers.keys())}")

        signer = SignerV4()
        # 使用param中保存的service和region（如果有），否则使用默认配置
        service = getattr(param, 'service', self.config.SERVICE)
        region = getattr(param, 'region', self.config.REGION)

        credentials = Credentials(
            self.config.ACCESS_KEY,
            self.config.SECRET_KEY,
            service,
            region
        )
        signer.sign(param, credentials)

        print(f"  Headers after signing: {list(param.headers.keys())}")
        if 'Authorization' in param.headers:
            auth_value = param.headers['Authorization']
            print(f"  Authorization: {auth_value[:50]}..." if len(auth_value) > 50 else f"  Authorization: {auth_value}")
        else:
            print(f"  [WARNING] Authorization header NOT FOUND after signing!")
    
    def make_request(
        self,
        action: str,
        body: Dict[str, Any],
        version: Optional[str] = None,
        service: Optional[str] = None,
        region: Optional[str] = None
    ) -> Dict[str, Any]:
        """发起API请求

        Args:
            action: API动作
            body: 请求体
            version: API版本 (可选，用于IAM等特殊服务)
            service: 服务名称 (可选，用于IAM等特殊服务)
            region: 区域 (可选)
        """
        # 使用传入的参数或默认配置
        use_version = version or self.config.VERSION

        # 调试输出
        print(f"\n[DEBUG] API Request:")
        print(f"  Action: {action}")
        print(f"  Version: {use_version}")
        if service:
            print(f"  Service: {service}")
        if region:
            print(f"  Region: {region}")
        print(f"  Body: {json.dumps(body, indent=2, ensure_ascii=False)}")

        # 创建签名参数
        param = self._create_signature_params(action, body, version, service, region)

        # 签名请求
        self._sign_request(param)

        # 构建URL
        url = f"{self.config.get_base_url()}?Action={action}&Version={use_version}&X-Account-Id={self.config.ACCOUNT_ID}"
        
        try:
            # 发送请求
            response = self.session.post(
                url,
                headers=dict(param.headers),
                data=param.body,
                timeout=self.config.REQUEST_TIMEOUT,
                verify=False
            )

            # 解析响应（在检查状态之前，这样即使是错误也能看到响应体）
            try:
                result = response.json()
            except json.JSONDecodeError:
                result = {"error": "Failed to parse response", "text": response.text}

            # 检查响应状态
            if response.status_code >= 400:
                # 打印完整的错误响应以便调试
                print(f"\n[DEBUG] Error Response:")
                print(f"  Status Code: {response.status_code}")
                print(f"  Response Body: {json.dumps(result, indent=2, ensure_ascii=False)}")

                # 对于4xx/5xx错误，尝试提取错误信息
                error_msg = result.get("ResponseMetadata", {}).get("Error", {}).get("Message") or \
                           result.get("error") or \
                           response.text
                raise Exception(f"API Error ({response.status_code}): {error_msg}")

            # 检查业务状态 - API返回Result字段表示成功
            # 有些接口返回BaseResp，有些直接返回Result
            if 'Result' in result:
                return result.get('Result', {})
            elif 'BaseResp' in result:
                base_resp = result.get('BaseResp', {})
                if base_resp.get('StatusCode', 0) != 0:
                    error_msg = base_resp.get('StatusMessage', 'Unknown error')
                    raise Exception(f"API Error: {error_msg}")
                return result
            else:
                # 直接返回结果
                return result
            
        except requests.exceptions.RequestException as e:
            raise Exception(f"Request failed: {str(e)}")
        except json.JSONDecodeError as e:
            raise Exception(f"Failed to parse response: {str(e)}")
    
    def get_workspace_id(self, workspace_id: Optional[str] = None) -> str:
        """获取工作空间ID"""
        return self.config.get_workspace_id(workspace_id)

    # ==================== IAM操作 ====================

    def call_iam_api(self, action: str, body: Dict[str, Any]) -> Dict[str, Any]:
        """调用IAM API的通用方法

        Args:
            action: IAM API动作名称
            body: 请求体

        Returns:
            Dict: API响应结果
        """
        # 获取IAM配置
        iam_config = self.config.get_iam_config()

        # 使用IAM服务配置发起请求
        return self.make_request(
            action=action,
            body=body,
            version=iam_config['version'],
            service=iam_config['service'],
            region=iam_config['region']
        )

    def create_user(
        self,
        username: str,
        password: str,
        email: Optional[str] = None,
        display_name: Optional[str] = None,
        role_name: str = 'TenantMember',
        status: int = 1,
        source: str = 'Platform'
    ) -> Dict[str, Any]:
        """创建用户 (使用IAM服务配置)

        Args:
            username: 用户名 (必需)
            password: 密码 (必需)
            email: 邮箱 (可选)
            display_name: 显示名称 (可选)
            role_name: 角色名称 (默认: TenantMember)
            status: 状态 (默认: 1-启用)
            source: 来源 (默认: Platform)

        Returns:
            Dict: 创建结果
        """
        # 构建请求体 - Password是必需参数
        body = {
            'UserName': username,
            'Password': password,
            'RoleName': role_name,
            'Status': status,
            'Source': source
        }

        # 添加可选参数
        if email:
            body['Email'] = email

        if display_name:
            body['DisplayName'] = display_name

        # 使用call_iam_api方法
        return self.call_iam_api('CreateUser', body)

    def get_user_by_name(self, username: str) -> Dict[str, Any]:
        """通过用户名获取用户信息

        Args:
            username: 用户名

        Returns:
            Dict: 用户信息
        """
        response = self.call_iam_api('GetUser', {'Name': username})

        # 检查响应格式
        if isinstance(response, dict):
            # 可能直接返回User对象
            if response.get('ID'):
                return response
            # 或者在User字段中
            elif response.get('User'):
                return response['User']

        raise Exception(f"User not found: {username}")

    def list_workspaces(self, page_number: int = 1, page_size: int = 100) -> Dict[str, Any]:
        """获取工作空间列表

        Args:
            page_number: 页码
            page_size: 每页数量

        Returns:
            Dict: 工作空间列表响应
        """
        return self.call_iam_api('ListWorkspace', {
            'ListOpt': {
                'PageNumber': page_number,
                'PageSize': page_size
            }
        })

    def get_workspace_by_username(self, username: str) -> str:
        """通过用户名获取个人空间ID

        个人空间ID遵循模式: personal-{UserID}

        Args:
            username: 用户名，如 "2019010471"

        Returns:
            str: 工作空间ID (格式: personal-{UserID})

        Raises:
            Exception: 用户不存在或未找到个人空间
        """
        # 步骤1: 获取用户信息
        user = self.get_user_by_name(username)
        user_id = user.get('ID')

        # 步骤2: 根据模式生成个人空间ID
        # 个人空间ID格式: personal-{UserID}
        workspace_id = f"personal-{user_id}"

        # 步骤3: 验证工作空间是否存在
        try:
            response = self.call_iam_api('GetWorkspace', {'ID': workspace_id})
            workspace = response.get('Item', response)

            if workspace and workspace.get('ID'):
                return workspace.get('ID')
        except Exception:
            # 如果直接获取失败，尝试通过列表查找
            pass

        # 备选方案: 通过列表查找（当模式不适用时）
        workspace_response = self.list_workspaces()

        # 提取工作空间列表
        workspaces = []
        if isinstance(workspace_response, dict):
            if workspace_response.get('Items'):
                workspaces = workspace_response['Items']
            elif workspace_response.get('Result') and workspace_response['Result'].get('Items'):
                workspaces = workspace_response['Result']['Items']

        # 筛选个人空间
        for workspace in workspaces:
            if workspace.get('OwnerID') == user_id:
                return workspace.get('ID')

        raise Exception(f"No personal workspace found for user: {username}")